//
// Created by DELL on 2023/9/5.
//

// https://runebook.dev/zh/docs/cpp/thread/barrier
//类模板 std::barrier 提供了一种线程协调机制，该机制最多允许预期数量的线程阻塞，
// 直到预期数量的线程到达屏障。与 std::latch 不同，屏障是可重用的：
// 一旦到达的线程从屏障阶段的同步点解除阻塞，就可以重用相同的屏障。
//
//一个屏障对象的生命周期由一连串的屏障阶段组成。每个阶段都定义了一个相位同步点.
// 在阶段期间到达屏障的线程可以通过调用 wait 在阶段同步点上阻塞，并在运行阶段完成步骤时被解除阻塞。


#include <barrier>
#include <iostream>
#include <string>
#include <thread>
#include <vector>

int main() {
    const auto workers = { "anil", "busara", "carl" };

    auto on_completion = []() noexcept {
        // 这里不需要加锁
        static auto phase = "... done\n" "Cleaning up...\n";
        std::cout << phase;
        phase = "... done\n";
    };
    std::barrier sync_point(std::ssize(workers), on_completion);

    auto work = [&](const std::string& name) {
        std::string product = "  " + name + " worked\n";
        std::cout << product;  // 好的，op<< 调用是原子的
        sync_point.arrive_and_wait();

        product = "  " + name + " cleaned\n";
        std::cout << product;
        sync_point.arrive_and_wait();
        std::cout << name  +" finished\n";
    };

    std::cout << "Starting...\n";
    std::vector<std::thread> threads;
    for (auto const& worker : workers) {
        threads.emplace_back(work, worker);
    }
    for (auto& thread : threads) {
        thread.join();
    }
}